﻿using System;
using System.Windows;
using System.Xml.Serialization;

namespace XDCCManager
{
	/// <summary>
	/// Interaction logic for App.xaml
	/// </summary>
	public partial class App : Application
	{
		private void Application_Startup(object sender, StartupEventArgs e)
		{
			LoadData();
			XDCCManager.Model.ActionQueueContext actionQueue = FindResource("ActionQueueContextDataSource") as XDCCManager.Model.ActionQueueContext;
			XDCCManager.Model.ServedFilesContext servedFiles = FindResource("ServedFilesContextDataSource") as XDCCManager.Model.ServedFilesContext;
			new XDCCManager.Network.IRC.PackUpdatesManager(actionQueue.Actions, servedFiles.Packs);
			System.AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler((eSender, eArgs) =>
			{
				if (System.Diagnostics.Debugger.IsAttached)
				{
					// An unhandled exception has occurred; break into the debugger
					System.Diagnostics.Debugger.Break();
				}
			});
		}

		private void Application_Exit(object sender, ExitEventArgs e)
		{
			SaveData();
			if (XDCCManager.Network.IRC.ServerConnection.Instance.Connecting)
				XDCCManager.Network.IRC.ServerConnection.Instance.CancelConnect();
			if (XDCCManager.Network.IRC.ServerConnection.Instance.Connected)
				XDCCManager.Network.IRC.ServerConnection.Instance.Disconnect();
			XDCCManager.Model.ServedFilesContext servedFiles = FindResource("ServedFilesContextDataSource") as XDCCManager.Model.ServedFilesContext;
			XDCCManager.Model.ActionQueueContext actionQueue = FindResource("ActionQueueContextDataSource") as XDCCManager.Model.ActionQueueContext;
			servedFiles.Packs.Clear();
			actionQueue.Actions.Clear();
		}

		private static System.IO.IsolatedStorage.IsolatedStorageFile GetStorage()
		{
			try
			{
				return System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
			}
			catch (System.IO.IsolatedStorage.IsolatedStorageException)
			{
			}
			try
			{
				return System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForAssembly();
			}
			catch (System.IO.IsolatedStorage.IsolatedStorageException)
			{
			}
			return null;
		}

		private void LoadData()
		{
			System.IO.IsolatedStorage.IsolatedStorageFile isf = GetStorage();
			Attributes.StorageFileAttribute sf = null;
			XDCCManager.Model.ServerContext serverContext = FindResource("ServerContextDataSource") as XDCCManager.Model.ServerContext;
			serverContext.Servers.Clear();
			serverContext.CurrentServer = null;
			sf = serverContext.GetType().GetCustomAttributes(typeof(Attributes.StorageFileAttribute), false)[0] as Attributes.StorageFileAttribute;
			if (isf.FileExists(sf.FileName))
			{
				using (System.IO.Stream source = isf.OpenFile(sf.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
				{
					XDCCManager.Model.ServerContext serverContext2 = Unserialize<XDCCManager.Model.ServerContext>(source);
					if (serverContext2 != null)
						foreach (var server in serverContext2.Servers)
							serverContext.Servers.Add(server);
				}
			}
			lastUpdate = DateTime.Now;
		}

		private void SaveData()
		{
			System.IO.IsolatedStorage.IsolatedStorageFile isf = GetStorage();
			Attributes.StorageFileAttribute sf = null;
			XDCCManager.Model.ServerContext serverContext = FindResource("ServerContextDataSource") as XDCCManager.Model.ServerContext;
			sf = serverContext.GetType().GetCustomAttributes(typeof(Attributes.StorageFileAttribute), false)[0] as Attributes.StorageFileAttribute;
			using (System.IO.Stream source = isf.OpenFile(sf.FileName, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
			{
				Serialize<XDCCManager.Model.ServerContext>(serverContext, source);
			}
		}

		private void Application_Deactivated(object sender, EventArgs e)
		{
			//DateTime dt = lastUpdate;
			//dt.AddMinutes(10);
			//if (dt < DateTime.Now)
			//{
			//    SaveData();
			//}
		}

		private T Unserialize<T>(System.IO.Stream source, params Type[] addTypes) where T: class
		{
			XmlSerializer serializer = new XmlSerializer(typeof(T), addTypes);
			try
			{
				return serializer.Deserialize(source) as T;
			}
			catch (InvalidOperationException)
			{
				return null;
			}
		}

		private void Serialize<T>(T source, System.IO.Stream destination, params Type[] addTypes) where T : class
		{
			XmlSerializer serializer = new XmlSerializer(typeof(T), addTypes);
			serializer.Serialize(destination, source);
		}

		private DateTime lastUpdate;

		private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
		{
			if (System.Diagnostics.Debugger.IsAttached)
			{
				// An unhandled exception has occurred; break into the debugger
				System.Diagnostics.Debugger.Break();
			}
		}
	}
}
